package com.yc.thread;

/**
 * @program: concurrent
 * @description: 生产者消费者
 * @author: zy
 * @create: 2022-01-10 13:50
 */
public class Test17_producerConsumer {
    public static void main(String[] args) {

        AppleBox ab = new AppleBox();

        Producer p = new Producer(ab);
        Producer c = new Producer(ab);
        Producer c2 = new Producer(ab);

        Consumer cd = new Consumer(ab);

        new Thread(p).start();
        new Thread(c).start();
        new Thread( c2 ).start();

        new Thread(cd).start();

    }
}

//待处理的消息
class Apple {
    String id;
    Apple(   String id) {
        this.id = id;
    }
    @Override
    public String toString() {
        return "apple: " + id;
    }
}
//中间缓存区
class AppleBox {
    int index = 0;
    Apple[] apples = new Apple[5];   //有界       =>队列

    //存消息
    public  synchronized  void deposite(Apple apple) {
        //  5 == 5
        while(   index==apples.length   ){
//            try {
//                Thread.sleep(100);  // sleep
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
            try {
                this.wait(    );
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        this.notifyAll();
        apples[index]=apple;
        index++;
    }
    //取消息
    public synchronized   Apple withdraw() {
        // 0==0
        while(  index==0 ){
//            try {
//               Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
            try {
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        this.notifyAll();
        index--;
        return apples[index];
    }

}

class Producer implements Runnable {
    AppleBox ab = null;   //生产和消费对应的资源是同一个，

    Producer(AppleBox ab) {
        this.ab = ab;
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            //创建消息
            Apple a = new Apple(Thread.currentThread().getName()+"牌:"+  i   );
            ab.deposite(      a   );
            System.out.println(Thread.currentThread().getName() + "生产了:" + a);
            try {
                Thread.sleep((int) (Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

class Consumer implements Runnable {
    AppleBox ab = null;

    Consumer(AppleBox ab) {
        this.ab = ab;
    }

    @Override
    public void run() {
        //只要appleBox中有苹果， 则一直循环.
        while(  ab.index>0  ) {
            //for (int i = 0; i < 5; i++) {
            Apple a = ab.withdraw();
            System.out.println(Thread.currentThread().getName() + "消费了" + a);
            try {
                Thread.sleep((int) (Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // }
        }
    }

}


